Skip to content

update the faces of clean air page#3822

Merged
Baalmart merged 5 commits into
stagingfrom
chore/empty-state
Jul 13, 2026
Merged

update the faces of clean air page#3822
Baalmart merged 5 commits into
stagingfrom
chore/empty-state

Conversation

@OchiengPaul442

@OchiengPaul442 OchiengPaul442 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Status of maturity (all need to be checked before merging):

  • I've tested this locally
  • I consider this code done

Screenshots (optional)

Summary by CodeRabbit

  • New Features
    • Added a new “Selfies” page for the Africa Clean Air Forum 2026, including an interactive carousel with auto-advance, loading/error/empty states, pagination, keyboard navigation, and swipe support (with reduced-motion support).
  • UI Improvements
    • Refreshed responsive typography and carousel layout for clearer display on all screen sizes.
    • Updated QR code button styling and adjusted QR placement across the experience (added to leaderboard and selfies; removed from landing and quiz).
  • Navigation
    • Added “Clean Air Faces” to the footer, linking to the Selfies page.

…, and Selfies screens

- Implemented QrCodeButton component with updated styles and functionality.
- Integrated QrCodeButton into LeaderboardScreen, QuizScreen, and SelfiesScreen for enhanced user interaction.
- Adjusted layout and styles for better responsiveness and visual consistency across screens.
- Added new Selfies route and screen to display user-submitted selfies from the Africa Clean Air Forum.
@OchiengPaul442 OchiengPaul442 self-assigned this Jul 13, 2026
@OchiengPaul442
OchiengPaul442 requested a review from Baalmart July 13, 2026 15:59
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf2c08fa-9bb3-4392-ac72-1ca7970035c4

📥 Commits

Reviewing files that changed from the base of the PR and between 77bec0b and f4288c8.

📒 Files selected for processing (3)
  • src/website/src/components/clean-air-forum-2026/selfie-components.tsx
  • src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx
  • src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx
  • src/website/src/components/clean-air-forum-2026/selfie-components.tsx
  • src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx

📝 Walkthrough

Walkthrough

Adds a Clean Air Forum 2026 Selfies route with metadata, footer navigation, a client-side selfie carousel, QR integration, and responsive layout refinements across related forum screens.

Changes

Clean Air Forum selfie experience

Layer / File(s) Summary
Selfie carousel components and interactions
src/website/src/components/clean-air-forum-2026/selfie-components.tsx
Adds animated selfie cards and states, responsive pagination, reduced-motion handling, keyboard navigation, and swipe gestures.
Selfie carousel behavior and states
src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx
Fetches and polls submissions, manages responsive pages and auto-advance, and renders loading, error, empty, and content states.
Selfies route and navigation wiring
src/website/src/app/(programs)/africa-clean-air-forum-2026/selfies/page.tsx, src/website/src/components/layout/Footer.tsx
Adds the routed page with generated metadata and exposes it through the footer About links.
Forum QR and responsive layout updates
src/website/src/components/clean-air-forum-2026/QrCodeButton.tsx, src/website/src/features/clean-air-forum-2026/screens/*, src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx
Updates QR styling and placement, removes QR controls from landing and quiz screens, and changes title sizing, overflow, and container widths across forum screens.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SelfiesRoute
  participant SelfiesScreen
  participant facesOfCleanAirService
  SelfiesRoute->>SelfiesScreen: render selfie screen
  SelfiesScreen->>facesOfCleanAirService: getSubmissions(event id)
  facesOfCleanAirService-->>SelfiesScreen: return submissions
  SelfiesScreen->>SelfiesScreen: paginate and render carousel
Loading

Possibly related PRs

Suggested reviewers: baalmart

Poem

Selfies sail through pages bright,
QR pixels guide the light.
Titles flex and layouts flow,
Polling keeps the wall aglow.
Clean air, clear screens, hooray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the PR and reasonably reflects the main Faces of Clean Air updates, though it is broad.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/empty-state

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

New azure website changes available for preview here

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx (2)

498-504: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Dead branch in the auto-advance timer.

Both arms of the if call goToRelativePage(1), so the conditional does nothing but slow down the reader. Collapse it to a single call.

♻️ Proposed simplification
-    const carouselTimer = window.setTimeout(() => {
-      if (totalSlides > 1 && page < totalSlides - 1) {
-        goToRelativePage(1);
-        return;
-      }
-      goToRelativePage(1);
-    }, CAROUSEL_INTERVAL_MS);
+    const carouselTimer = window.setTimeout(() => {
+      goToRelativePage(1);
+    }, CAROUSEL_INTERVAL_MS);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx`
around lines 498 - 504, In the carouselTimer callback on SelfiesScreen, remove
the redundant totalSlides/page conditional and invoke goToRelativePage(1) once
after the timeout, preserving the existing interval and auto-advance behavior.

329-333: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use cn() for conditional class composition.

This className composes a static base with a conditional segment via a template literal + ternary. The repo standard is cn() from @/lib/utils. The same pattern recurs elsewhere in this file (e.g. the loading/content wrapper ternaries around Lines 729-749 and 805-818), so worth aligning them as you touch this.

As per coding guidelines: "Use cn() from @/lib/utils for conditional Tailwind class composition."

♻️ Proposed fix (add the import, then swap the template literal)
+import { cn } from '`@/lib/utils`';
-            className={`relative h-2.5 overflow-hidden rounded-full border border-white/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent ${
-              isActive
-                ? 'w-11 bg-white/30'
-                : 'w-2.5 bg-white/30 hover:bg-white/50'
-            }`}
+            className={cn(
+              'relative h-2.5 overflow-hidden rounded-full border border-white/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent',
+              isActive ? 'w-11 bg-white/30' : 'w-2.5 bg-white/30 hover:bg-white/50',
+            )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx`
around lines 329 - 333, Update the conditional class composition for the
indicator element in SelfiesScreen using the repository’s cn() utility from
`@/lib/utils` instead of a template literal and ternary. Add the import if needed,
and align the related conditional className expressions in the loading/content
wrapper sections with cn() while preserving their existing classes and behavior.

Source: Coding guidelines

src/website/src/app/(programs)/africa-clean-air-forum-2026/selfies/page.tsx (1)

4-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Centralize this page’s metadata in METADATA_CONFIGS.
It’s still defining title/description/keywords inline; adding a config entry keeps the program pages consistent and avoids duplicated SEO strings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/website/src/app/`(programs)/africa-clean-air-forum-2026/selfies/page.tsx
around lines 4 - 11, Move the inline title, description, keywords, and URL
configuration from the page’s generateMetadata call into the centralized
METADATA_CONFIGS entry for the Africa Clean Air Forum 2026 selfies page. Update
the page to reference that config while preserving the existing generated
metadata values and behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx`:
- Around line 293-298: The leaderboard title can be clipped on narrow screens
because its container hides overflow while the text cannot wrap. In
src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx
lines 293-298, add truncation styling to the title span; apply the same change
in the isLeaderboardStage title span at
src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx lines
1110-1112 so both render an ellipsis instead of clipping.

---

Nitpick comments:
In `@src/website/src/app/`(programs)/africa-clean-air-forum-2026/selfies/page.tsx:
- Around line 4-11: Move the inline title, description, keywords, and URL
configuration from the page’s generateMetadata call into the centralized
METADATA_CONFIGS entry for the Africa Clean Air Forum 2026 selfies page. Update
the page to reference that config while preserving the existing generated
metadata values and behavior.

In `@src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx`:
- Around line 498-504: In the carouselTimer callback on SelfiesScreen, remove
the redundant totalSlides/page conditional and invoke goToRelativePage(1) once
after the timeout, preserving the existing interval and auto-advance behavior.
- Around line 329-333: Update the conditional class composition for the
indicator element in SelfiesScreen using the repository’s cn() utility from
`@/lib/utils` instead of a template literal and ternary. Add the import if needed,
and align the related conditional className expressions in the loading/content
wrapper sections with cn() while preserving their existing classes and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 234af358-1b52-4f06-b21a-f29e05a5c8e3

📥 Commits

Reviewing files that changed from the base of the PR and between 52d669c and 3cdc0f8.

📒 Files selected for processing (7)
  • src/website/src/app/(programs)/africa-clean-air-forum-2026/selfies/page.tsx
  • src/website/src/components/clean-air-forum-2026/QrCodeButton.tsx
  • src/website/src/components/layout/Footer.tsx
  • src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/QuizScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx
  • src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx

Comment thread src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

New azure website changes available for preview here

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/website/src/components/clean-air-forum-2026/selfie-components.tsx (1)

345-349: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Compose the conditional classes with cn().

This template-literal concatenation mixes a static base with an isActive branch. Routing it through cn() keeps composition consistent and avoids stray-space/merge quirks.

♻️ Example
-            className={`relative h-2.5 overflow-hidden rounded-full border border-white/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent ${
-              isActive
-                ? 'w-11 bg-white/30'
-                : 'w-2.5 bg-white/30 hover:bg-white/50'
-            }`}
+            className={cn(
+              'relative h-2.5 overflow-hidden rounded-full border border-white/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent',
+              isActive ? 'w-11 bg-white/30' : 'w-2.5 bg-white/30 hover:bg-white/50',
+            )}

Add import { cn } from '@/lib/utils'; at the top.

As per coding guidelines: "Use cn() from @/lib/utils for conditional Tailwind class composition."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/website/src/components/clean-air-forum-2026/selfie-components.tsx` around
lines 345 - 349, Update the conditional class composition on the affected
element to use the `cn()` utility from `@/lib/utils` instead of template-literal
concatenation, preserving the static classes and the existing `isActive`
width/background branches.

Source: Coding guidelines

src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx (1)

119-125: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Auto-advance branch is a no-op — both paths do the same thing.

The if (totalSlides > 1 && page < totalSlides - 1) block and the fall-through both call goToRelativePage(1), and that helper already wraps via modulo, so the last-page case loops to 0 regardless. The conditional is dead. If you intended different last-page behavior (e.g. pause, or jump-to-0 without the wrap), that logic is missing; otherwise collapse it.

♻️ Collapse to the effective behavior
-    const carouselTimer = window.setTimeout(() => {
-      if (totalSlides > 1 && page < totalSlides - 1) {
-        goToRelativePage(1);
-        return;
-      }
-      goToRelativePage(1);
-    }, CAROUSEL_INTERVAL_MS);
+    const carouselTimer = window.setTimeout(() => {
+      goToRelativePage(1);
+    }, CAROUSEL_INTERVAL_MS);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx`
around lines 119 - 125, Remove the redundant conditional inside the
carouselTimer callback in SelfiesScreen, leaving a single goToRelativePage(1)
call so auto-advance preserves the existing modulo-wrapping behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/website/src/components/clean-air-forum-2026/selfie-components.tsx`:
- Around line 90-91: Update the location fallback in the selfie card component
to use a neutral description instead of the hardcoded Pretoria location.
Preserve trimmed submission.locationName values, and ensure the resulting
location used by the image alt text does not assert a specific place when
locationName is absent.

---

Nitpick comments:
In `@src/website/src/components/clean-air-forum-2026/selfie-components.tsx`:
- Around line 345-349: Update the conditional class composition on the affected
element to use the `cn()` utility from `@/lib/utils` instead of template-literal
concatenation, preserving the static classes and the existing `isActive`
width/background branches.

In `@src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx`:
- Around line 119-125: Remove the redundant conditional inside the carouselTimer
callback in SelfiesScreen, leaving a single goToRelativePage(1) call so
auto-advance preserves the existing modulo-wrapping behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a7b52bc8-5098-4d21-b3c7-8e950eea6eef

📥 Commits

Reviewing files that changed from the base of the PR and between 3cdc0f8 and 77bec0b.

📒 Files selected for processing (8)
  • src/website/src/components/clean-air-forum-2026/QrCodeButton.tsx
  • src/website/src/components/clean-air-forum-2026/selfie-components.tsx
  • src/website/src/components/layout/Footer.tsx
  • src/website/src/features/clean-air-forum-2026/screens/LandingScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/QuizScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx
  • src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx
💤 Files with no reviewable changes (2)
  • src/website/src/features/clean-air-forum-2026/screens/LandingScreen.tsx
  • src/website/src/features/clean-air-forum-2026/screens/QuizScreen.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/website/src/components/layout/Footer.tsx
  • src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx
  • src/website/src/components/clean-air-forum-2026/QrCodeButton.tsx
  • src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx

Comment thread src/website/src/components/clean-air-forum-2026/selfie-components.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

New azure website changes available for preview here

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refreshes the Africa Clean Air Forum 2026 “Faces of Clean Air” experience by introducing a dedicated Selfies page/carousel, refining responsive header typography/layout, and repositioning the QR entry point to the screens where participation is most relevant.

Changes:

  • Added a new /africa-clean-air-forum-2026/selfies route with an interactive, auto-advancing selfie carousel and loading/error/empty states.
  • Updated header typography/truncation to be more responsive across CAF 2026 screens.
  • Moved/remodeled the QR button placement (added to Selfies + Leaderboard; removed from Landing + Quiz) and updated footer navigation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/website/src/features/faces-of-clean-air/FacesOfCleanAirPage.tsx Responsive header truncation + overflow adjustments for the existing faces/leaderboard carousel experience.
src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx New CAF 2026 selfies screen with polling, carousel interaction, pagination, and QR entry point.
src/website/src/features/clean-air-forum-2026/screens/QuizScreen.tsx Updated header sizing/layout; removed QR button and reduced max content width.
src/website/src/features/clean-air-forum-2026/screens/LeaderboardScreen.tsx Updated header truncation/layout; added QR button and adjusted error card sizing.
src/website/src/features/clean-air-forum-2026/screens/LandingScreen.tsx Removed QR button from the landing screen.
src/website/src/components/layout/Footer.tsx Added a “Clean Air Faces” footer link to the new selfies route.
src/website/src/components/clean-air-forum-2026/selfie-components.tsx New shared selfie UI primitives/hooks (card, pagination, keyboard + swipe handling).
src/website/src/components/clean-air-forum-2026/QrCodeButton.tsx Visual sizing/styling tweaks for the QR button.
src/website/src/app/(programs)/africa-clean-air-forum-2026/selfies/page.tsx New Next.js route + metadata for the selfies page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/website/src/features/clean-air-forum-2026/screens/SelfiesScreen.tsx Outdated
Comment thread src/website/src/components/clean-air-forum-2026/selfie-components.tsx Outdated
</motion.header>

<main className="mx-auto flex min-h-0 w-full max-w-[1200px] flex-1 items-center justify-center pt-2 sm:min-h-[60svh] sm:flex-none sm:pt-10">
<main className="mx-auto flex min-h-0 w-full max-w-[1200px] flex-1 items-center justify-center overflow-hidden pt-2 sm:min-h-[60svh] sm:flex-none sm:pt-10">
@github-actions

Copy link
Copy Markdown
Contributor

New azure website changes available for preview here

@Baalmart
Baalmart merged commit 522c866 into staging Jul 13, 2026
27 checks passed
@Baalmart
Baalmart deleted the chore/empty-state branch July 13, 2026 20:36
@Baalmart Baalmart mentioned this pull request Jul 13, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants